{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Sounds;

interface

uses Classes, UIObjects, Sound, AHMTypes, XMLHelper;

{$IFDEF DESIGNER}
const
  MODIFY_CAPTION = 'Load Sound';
  PREVIEW_CAPTION = 'Preview Sound';

  // Property categories and hints for designer
  CAT_SOUND = 'Sound';
  HINT_FILENAME = 'specifies a file name for this sound effect in the ' +
                  'theme resources directory';
{$ENDIF}


type
  TAHMSound = class(TAHMUIObject)
  private
    FSound: TAHMWAVSound;
    FFilename: TAHMFilename;
    FLoaded: Boolean;
  protected
    procedure SetFilename(Filename: TAHMFilename);
    procedure ClearProperties; override;
  public
    constructor Create(const Name: String); override;
    destructor Destroy; override;
    property Sound: TAHMWAVSound read FSound;
    function RenderPreview: Boolean; override;
    function ModifyActions: Integer; override;
    function Modify(Action: Integer): Boolean; override;
    function ModifyCaption(Action: Integer): String; override;
    procedure Load(const FileName: String);
    procedure PlaySound;
    procedure Assign(Source: TPersistent); override;
    procedure SaveAsXML(Lines: TStrings); override;
    procedure ParseFromXML(XML: TAHMXMLHelper); override;
    procedure BuildProperties(Properties: TAHMUIPropertyList); override;
  published
    property Filename: TAHMFilename read FFilename write SetFilename;
  end;

  TAHMSoundList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddSound(const InheritFrom, NewName: String): TAHMSound; overload;
    function GetSound(const Name: String): TAHMSound;
    function LoadSounds: Boolean;
  end;


implementation

uses SysUtils, Screen, TagNames, XMLTags, ApplicationManager;


constructor TAHMSoundList.Create;
begin
  inherited Create;

  XMLTagName := TAG_SOUNDS;
  ChildClass := TAHMSound;
end;

function TAHMSoundList.AddSound(const InheritFrom, NewName: String): TAHMSound;
begin
  Result := TAHMSound(Inherit(InheritFrom, NewName));
end;

function TAHMSoundList.GetSound(const Name: String): TAHMSound;
begin
  Result := TAHMSound(GetObject(Name));
end;

function TAHMSoundList.LoadSounds: Boolean;
var
  i: Integer;
  oSound: TAHMSound;
begin
  for i := 0 to Pred(Count) do
  begin
    oSound := TAHMSound(Objects[i]);
    oSound.Load(oSound.Filename);
  end;

  // We should add some more sophisticated error checking later
  Result := True;
end;


//----------------------------------------------------------------------------//

constructor TAHMSound.Create(const Name: String);
begin
  inherited Create(Name);

  XMLTagName := TAG_SOUND;
  ObjectType := otSounds;
  ImageIndex := Ord(otSounds);

  FSound := TAHMWAVSound.Create;
end;

destructor TAHMSound.Destroy;
begin
  FSound.Free;

  inherited Destroy;
end;

procedure TAHMSound.SetFilename(Filename: TAHMFilename);
begin
  // If filename is changed after we're loaded then reload sound
  if FLoaded and (Filename <> FFilename) then
  begin
    FLoaded := False;
    Load(Filename);
  end;

  FFilename := Filename;
end;

procedure TAHMSound.ClearProperties;
begin
  inherited;

  // Clear custom sound properties
  FFilename := '';
  FLoaded := False;
end;

function TAHMSound.RenderPreview: Boolean;
begin
{$IFDEF DESIGNER}
  with ScreenInstance.Viewport do
  begin
    Canvas.DesignerBackground(ViewportRect);
    Canvas.TextRect(ViewportRect, nil, 'Sound Filename: ' + FFilename);
  end;
{$ENDIF}
  Result := True;
end;

function TAHMSound.ModifyActions: Integer;
begin
  // Supports actions to load or preview sounds
  Result := 2;
end;

function TAHMSound.Modify(Action: Integer): Boolean;
var
  NewFile: String;
begin
  // Set default result - not modified
  Result := False;

  case Action of
    0: begin
         // Use theme manager to select and copy sound file
         NewFile := FFileName;
         Result := ApplicationManagerInstance.ThemeManager.AddThemeResource(NewFile, rtSound);
         if Result then SetFilename(NewFile);
         if Result then DoModified;
       end;
    1: begin
         // Play our sound
         if FLoaded then FSound.PlaySound;
       end;
  end;
end;

function TAHMSound.ModifyCaption(Action: Integer): String;
begin
{$IFDEF DESIGNER}
  case Action of
    0: Result := MODIFY_CAPTION;
    1: Result := PREVIEW_CAPTION;
    else Result := '';
  end;
{$ELSE}
  Result := '';
{$ENDIF}
end;

procedure TAHMSound.Load(const FileName: String);
var
  sResourceURL: String;
begin
  FFilename := FileName;
  if FLoaded then Exit;
  FLoaded := True;

  // Get theme resource URL to prefix sound location
  sResourceURL := ApplicationManagerInstance.ThemeManager.ThemeResourceURL;

  // Quick and dirty for now...
  if not FSound.LoadFromFile(sResourceURL + FFilename) then
    Exit;
end;

procedure TAHMSound.PlaySound;
begin
  // Play our sound (if sound effects are enabled)
  with ApplicationManagerInstance.PreferencesManager do
    if SoundEffects and FLoaded then FSound.PlaySound(SoundVolume);
end;

procedure TAHMSound.Assign(Source: TPersistent);
begin
  inherited Assign(Source);

  with Source as TAHMSound do
    Self.Filename := Filename;
end;

procedure TAHMSound.SaveAsXML(Lines: TStrings);
var
  oAncs: TAHMSound;
begin
  // Determine which ancestor to compare against - real or empty
  oAncs := TAHMSound(ObjectToCompare);

  // We need to explicitly save comments in overridden method
  SaveXMLComments(Lines);

  // Only populate attributes that differ from our ancestor
  if (Filename <> '') and (Filename <> oAncs.Filename) then
    Lines.Add(TABS[2] + TagBegin + EncodeXML(Filename) + TagEnd)
  else
    Lines.Add(TABS[2] + TagBegin + TagEnd);
end;

procedure TAHMSound.ParseFromXML(XML: TAHMXMLHelper);
var
  sValue: String;
begin
  // Just parse sound filename
  sValue := XML.GetValue;
  if sValue <> '' then FileName := sValue;
end;

procedure TAHMSound.BuildProperties(Properties: TAHMUIPropertyList);
begin
{$IFDEF DESIGNER}
  inherited;

  // Build custom sound properties
  Properties.Add('File Name', 'Filename', CAT_SOUND, HINT_FILENAME);
{$ENDIF}
end;


end.
